using System;
using System.Windows.Forms;
using HgAdapter;
using HogoLogic;
using ProjectView;

namespace HogoWinClient
{
	public partial class MainForm : Form
	{
		private static readonly string projectsStorageFilename = "projects";
		private static readonly string appearanceStorageFilename = "appearance";

		public MainForm()
		{
			InitializeComponent();
		}

		private void SaveState()
		{
			AppearanceSettings.Instance.DontShowToolTipForm = TipsForm.Instance.DontShow;
			AppearanceSettings.Instance.AnnotatePreferences = OptionsForm.Instance.AnnotatePreferences;
			AppearanceSettings.Instance.GetFilesPreferences = hogoFileSystemView.GetFilesPreferences;
			
			AppearanceSettings.SaveToFile(appearanceStorageFilename);

			HogoProjectList.SaveToFile(projectsStorageFilename);
		}

		private void LoadState()
		{
			AppearanceSettings.LoadFromFile(appearanceStorageFilename);

			TipsForm.Instance.DontShow = AppearanceSettings.Instance.DontShowToolTipForm;
			OptionsForm.Instance.AnnotatePreferences = AppearanceSettings.Instance.AnnotatePreferences;
			hogoFileSystemView.GetFilesPreferences = AppearanceSettings.Instance.GetFilesPreferences;

			HogoProjectList.LoadFromFile(projectsStorageFilename);
		}

		private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
		{
			SaveState();
		}
		

		private void MainForm_Shown(object sender, EventArgs e)
		{
			TipsForm.Instance.TryShowDialog();

			if (ProjectViewForm.Instance.ShowDialog(HogoProjectList.Instance) == DialogResult.OK)
			{
				if (ProjectViewForm.Instance.Result == ProjectSelectionResult.Clone)
					Clone();
				if (ProjectViewForm.Instance.Result == ProjectSelectionResult.Init)
					Init();
				if (ProjectViewForm.Instance.Result == ProjectSelectionResult.Make)
					Make();
				if (ProjectViewForm.Instance.Result.IsCustom)
					hogoFileSystemView.Open(ProjectViewForm.Instance.Result.SelectedProject.WorkingDir);
			}
		}



		private void MainForm_Load(object sender, EventArgs e)
		{
			LoadState();
		}

		private void MainForm_Activated(object sender, EventArgs e)
		{
			ProjectCommitInfo.Instance.Reload();
			hogoFileSystemView.Open(ProjectCommitInfo.Instance.ProjectPath);
		}

		#region Main Menu handlers
		private void initItem_Click(object sender, EventArgs e)
		{
			Init();
		}

		private void makeItem_Click(object sender, EventArgs e)
		{
			Make();
		}

		private void cloneItem_Click(object sender, EventArgs e)
		{
			Clone();
		}

		private void tipsItem_Click(object sender, EventArgs e)
		{
			TipsForm.Instance.ShowDialog();
		}

		private void aboutHogoItem_Click(object sender, EventArgs e)
		{
			AboutForm.Instance.ShowDialog();
		}

		private void preferencesItem_Click(object sender, EventArgs e)
		{
			OptionsForm.Instance.ShowDialog();
		}

		private void logItem_Click(object sender, EventArgs e)
		{
			string output = (new HgLog().Run());
		}

		private void commitItem_Click(object sender, EventArgs e)
		{
			Commit();
		}

		private void addItem_Click(object sender, EventArgs e)
		{
			Add();
		}

		private void removeItem_Click(object sender, EventArgs e)
		{
			Remove();
		}

		private void revertItem_Click(object sender, EventArgs e)
		{
			Revert();
		}

		private void annotateItem_Click(object sender, EventArgs e)
		{
			Annotate();
		}

		private void diffItem_Click(object sender, EventArgs e)
		{
			Diff();
		}

		private void exitItem_Click(object sender, EventArgs e)
		{
			Close();
		}
		#endregion

		#region Context Menu handlers
		private void annotateContextItem_Click(object sender, EventArgs e)
		{
			Annotate();
		}

		private void openContextItem_Click(object sender, EventArgs e)
		{
			Open();
		}

		private void diffContextItem_Click(object sender, EventArgs e)
		{
			Diff();
		}

		private void addContextItem_Click(object sender, EventArgs e)
		{
			Add();
		}

		private void commitContextItem_Click(object sender, EventArgs e)
		{
			Commit();
		}

		private void removeContextItem_Click(object sender, EventArgs e)
		{
			Remove();
		}

		private void revertContextItem_Click(object sender, EventArgs e)
		{
			Revert();
		}
		#endregion

		#region Tool Strip handlers
		private void commitButton_Click(object sender, EventArgs e)
		{
			Commit();
		}

		private void addButton_Click(object sender, EventArgs e)
		{
			Add();
		}

		private void diffButton_Click(object sender, EventArgs e)
		{
			Diff();
		}

		private void annotateButton_Click(object sender, EventArgs e)
		{
			Annotate();
		}

		private void revertButton_Click(object sender, EventArgs e)
		{
			Revert();
		}

		private void removeButton_Click(object sender, EventArgs e)
		{
			Remove();
		}
		#endregion

		#region Actions
		private void Init()
		{
			if (RepositoryEditorForm.Instance.ShowDialog() == System.Windows.Forms.DialogResult.OK)
			{
				if (RepositoryEditorForm.Instance.SelectedProject.Inited)
				{
					MessageBox.Show("This directory already has inited repository", 
						"Can't init repository",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error);
					return;
				}

				RepositoryEditorForm.Instance.SelectedProject.Init();
				if (!HogoProjectList.Instance.Add(RepositoryEditorForm.Instance.SelectedProject))
				{
					MessageBox.Show("This name or working dir already added to project list",
						"Can't add project",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error);
					return;
					
				}
				
				hogoFileSystemView.Open(RepositoryEditorForm.Instance.SelectedProject.WorkingDir);
			}
		}

		private void Make()
		{
			if (RepositoryEditorForm.Instance.ShowDialog() == System.Windows.Forms.DialogResult.OK)
			{
				if (!RepositoryEditorForm.Instance.SelectedProject.Inited)
				{
					MessageBox.Show("This directory hasn't inited repository",
						"Repository isn't found",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error);
					return;
				}

				if (!HogoProjectList.Instance.Add(RepositoryEditorForm.Instance.SelectedProject))
				{
					MessageBox.Show("This name or working dir already added to project list",
						"Can't add project",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error);
					return;

				}
				hogoFileSystemView.Open(RepositoryEditorForm.Instance.SelectedProject.WorkingDir);
			}
		}

		private void Clone()
		{

		}
		
		private void Commit()
		{
			if (commitDialog.ShowDialog(hogoFileSystemView.SelectedFsElement) == DialogResult.OK)
			{
				(new HgCommit()).Run(commitDialog.SelectedFsElement.BrackedFileName, commitDialog.CommitMessage);

				ProjectCommitInfo.Instance.Reload();
				hogoFileSystemView.Open(ProjectCommitInfo.Instance.ProjectPath);
			}
		}

		private void Add()
		{
			(new HgAdd()).Run(hogoFileSystemView.SelectedFsElement.BrackedFileName);

			ProjectCommitInfo.Instance.Reload();
			hogoFileSystemView.Open(ProjectCommitInfo.Instance.ProjectPath);
		}

		private void Diff()
		{
			string diffOutput = (new HgDiff()).Run(hogoFileSystemView.SelectedFsElement.BrackedFileName);
			diffDialog.ShowDialog(diffOutput);
		}

		private void Open()
		{
			openDialog.ShowDialog(hogoFileSystemView.SelectedFsElement.BrackedFileName);
		}

		private void Annotate()
		{
			string annotateOutput = (new HgAnnotate()).Run(hogoFileSystemView.SelectedFsElement.BrackedFileName);
			annotateDialog.ShowDialog(annotateOutput);
		}

		private void Remove()
		{
			(new HgRemove()).Run(hogoFileSystemView.SelectedFsElement.BrackedFileName);

			ProjectCommitInfo.Instance.Reload();
			hogoFileSystemView.Open(ProjectCommitInfo.Instance.ProjectPath);
		}

		private void Revert()
		{
			(new HgRevert()).Run(hogoFileSystemView.SelectedFsElement.BrackedFileName);

			ProjectCommitInfo.Instance.Reload();
			hogoFileSystemView.Open(ProjectCommitInfo.Instance.ProjectPath);
		}

		#endregion

		private void hogoFileSystemView_OnSelectedFsElementChanged(object sender, EventArgs e)
		{
			openContextItem.Enabled = hogoFileSystemView.SelectedFsElement.CanBeOpened;

			addItem.Enabled = 
				addButton.Enabled = 
				addContextItem.Enabled = 
				hogoFileSystemView.SelectedFsElement.CanBeAdded;
			
			commitItem.Enabled = 
				commitButton.Enabled = 
				commitContextItem.Enabled = 
				hogoFileSystemView.SelectedFsElement.CanBeComitted;

			annotateItem.Enabled = 
				annotateButton.Enabled = 
				annotateContextItem.Enabled = 
				hogoFileSystemView.SelectedFsElement.CanBeAnnotated;
			
			diffItem.Enabled = 
				diffButton.Enabled = 
				diffContextItem.Enabled = 
				hogoFileSystemView.SelectedFsElement.CanBeDiffed;

			removeItem.Enabled =
				removeButton.Enabled =
				removeContextItem.Enabled =
				hogoFileSystemView.SelectedFsElement.CanBeRemoved;

			revertItem.Enabled =
				revertButton.Enabled =
				revertContextItem.Enabled =
				hogoFileSystemView.SelectedFsElement.CanBeReverted;
		}
	}
}